import numpy as np
import json


class fdtd_interface:
    def __init__(self,paras):
        import environment_pool as env
        env.dx_pool = paras["dx"]
        print("dx_pool", env.dx_pool )
        env.dy_pool = paras["dy"]
        print("dy_pool",  env.dy_pool )
        env.dz_pool = paras["dz"]
        print("dz_pool", env.dz_pool )
        env.mesh_x0_pool = paras["mesh_x0"]
        print("mesh_x0_pool",  env.mesh_x0_pool)
        env.mesh_y0_pool = paras["mesh_y0"]
        print("mesh_y0_pool",  env.mesh_y0_pool)
        env.mesh_z0_pool = paras["mesh_z0"]
        print("mesh_z0_pool",  env.mesh_z0_pool)
        env.time_user_pool = paras["time_user"]
        print("time_user_pool",  env.time_user_pool)
        env.number_of_time_steps_pool = paras["number_of_time_steps"]
        print("number_of_time_steps_pool",  env.number_of_time_steps_pool)
        env.courant_factor_pool = paras["courant_factor"]
        print("courant_factor_pool",  env.courant_factor_pool)
        env.mesh_type_pool = paras["mesh_type"]
        print("mesh_type_pool",  env.mesh_type_pool)
        env.mesh_input_pool = paras["mesh_input"]
        print("mesh_input_pool",  env.mesh_input_pool)
        env.out_processing_file = paras["out_processing_file"]
        print("out_processing_file",  env.out_processing_file)
        env.fdtd_mesh_pool = Environment["fdtd_mesh"]
        print("fdtd_mesh_pool",  env.fdtd_mesh_pool)
    # 创建材料
    def create_material(self,Material):
        import environment_pool as env
        env.material_types_pool = Material
        print("material_types_pool",  env.material_types_pool)
    # 装载模型
    def create_model(self,Model):
        import environment_pool as env
        env.thin_wires_pool = Model["thin_wires"]
        print("thin_wires_pool",  env.thin_wires_pool)
        env.bricks_pool = Model["bricks"]
        print("bricks_pool",  env.bricks_pool)
        env.spheres_pool = Model["spheres"]
        print("spheres_pool",  env.spheres_pool)
        env.brian_pool = Model["brian"]
        print("brian_pool",  env.brian_pool)
        mapC2Ms = {}
        for mapC2Mkey in Model["mapC2M"]:
            mapC2Ms[int(mapC2Mkey)] = Model["mapC2M"][mapC2Mkey]
        env.mapC2M_pool = mapC2Ms
        print("mapC2Ms",env.mapC2M_pool)
    # 设置边界条件
    def set_boundary(self, Boundary):
        import environment_pool as env
        env.boundary_pool = Boundary
        print("Boundary",env.boundary_pool)

    # 设置激励源
    def create_source(self,Source):
        import environment_pool as env
        env.waveform_type_pool = Source["waveform_type"]
        print("waveform_type_pool",env.waveform_type_pool)
        env.f_sinwave_pool = Source["f_sinwave"]
        print("f_sinwave_pool",env.f_sinwave_pool)
        # 高斯脉冲
        env.setbandwidth_pool = Source["setbandwidth"]
        print("setbandwidth_pool",env.setbandwidth_pool)
        env.f_center_pool = Source["f_center"]
        print("f_center_pool",env.f_center_pool)
        #激励源
        env.src_pos_x_pool = Source["src_pos_x"]
        print("src_pos_x_pool",env.src_pos_x_pool)
        env.src_pos_y_pool = Source["src_pos_y"]
        print("src_pos_y_pool",env.src_pos_y_pool)
        env.src_pos_z_pool = Source["src_pos_z"]
        print("src_pos_z_pool",env.src_pos_z_pool)
        env.src_compoinent_pool = Source["src_compoinent"]
        print("src_compoinent_pool",env.src_compoinent_pool)
    def set_params(self,params):
        import environment_pool as env
        env.frequency_domain_pool["start"] = params["frequency_domain"]["start"]
        env.frequency_domain_pool["end"] = params["frequency_domain"]["end"]
        env.frequency_domain_pool["step"] = params["frequency_domain"]["step"]
        print("frequency_domain_pool", env.frequency_domain_pool)
    def run_simulate(self):
        import environment_pool as env
        import fdtd_solve as fs
        return fs.time
    # 计算吸收功率
    def calc_absorb_power(self):
        from calculate_absorb_power import calculate_absorb_power
        average_power_max,self.absorb_power,self.SAR,self.SurE = calculate_absorb_power()
        return average_power_max
    def ouput_absorb_power_vis(self,file,type=1):
        from calculate_absorb_power import output_data
        output_data(self.absorb_power,file,type)
    def ouput_SAR_vis(self,file,type=1):
        from calculate_absorb_power import output_data
        output_data(self.SAR,file,type)
    def ouput_SurE_vis(self,file,type=1):
        from calculate_absorb_power import output_data
        output_data(self.SurE,file,type)
    def set_cutplanes(self,out_file,cutplanes,ut_processing_file,type=1):
        from calculate_absorb_power import set_cutplanes
        set_cutplanes(out_file,cutplanes,ut_processing_file)

# 使用示例
if __name__ == '__main__':
    with open('data.json','r') as f:
        paras = json.load(f)


    #print(paras['Model'])
    from environment_pool import *
    Environment = paras['Environment'] 
    fdtd_inter0 = fdtd_interface(Environment)
    fdtd_inter0.set_boundary(paras["boundary"])
    fdtd_inter0.create_material(paras["material_types"])
    fdtd_inter0.create_source(paras["Source"])
    fdtd_inter0.create_model(paras["Model"])
    fdtd_inter0.set_params(paras["params"])


    from define_problem_space_parameters import *
    from define_geometry import *
    from define_sources_and_lumped_elements import *
    from define_output_parameters import *
    # initialize the problem space and parameters 4
    from initialize_fdtd_material_grid import *

    time  =  fdtd_inter0.run_simulate()
    average_power_max = fdtd_inter0.calc_absorb_power()
    from debug import printValue
   # printValue("average_power_max",average_power_max)
    if(Environment["out_field"]==0):
        fdtd_inter0.ouput_absorb_power_vis(Environment["out_file"],Environment["out_type"])
    elif(Environment["out_field"]==1):
        fdtd_inter0.ouput_SAR_vis(Environment["out_file"],Environment["out_type"])
    elif(Environment["out_field"]==2):
        fdtd_inter0.ouput_SurE_vis(Environment["out_file"],Environment["out_type"])
        

    cutplanes=[
        {'r5':np.array([0.014,0.014,0.014],dtype=np.float32),'iu':np.array([0.0,0.0,1.0],dtype=np.float32),'iv':np.array([1.0,0.0,0.0]),'flip':False},
        {'r5':np.array([0.014,0.014,0.014],dtype=np.float32),'iu':np.array([1.0,0.0,0.0],dtype=np.float32),'iv':np.array([0.0,1.0,0.0]),'flip':True},
    ]
    fdtd_inter0.set_cutplanes(Environment["out_file"],cutplanes,Environment["out_processing_file"])

    with open('result.txt','w') as f:
        f.write(f'{time} {average_power_max}') 